package com.xiang.community.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xiang.community.annotation.LoginRequired;
import com.xiang.community.bo.MessageBO;
import com.xiang.community.dto.ResultDTO;
import com.xiang.community.entity.DiscussPost;
import com.xiang.community.entity.User;
import com.xiang.community.enums.ResponseCodeEnum;
import com.xiang.community.message.MessageProducer;
import com.xiang.community.service.CommonService;
import com.xiang.community.service.DiscussPostService;
import com.xiang.community.service.UserService;
import com.xiang.community.utils.CookieUtil;
import com.xiang.community.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

import static com.xiang.community.constant.KafkaConstant.TOPIC_GOOD;
import static com.xiang.community.constant.LoginConstant.MAP_KEY_TOKEN;
import static com.xiang.community.constant.RedisUtilConstant.PREFIX_DISCUSS_POST;
import static com.xiang.community.constant.RedisUtilConstant.PREFIX_USER_ID;

/**
 * @author qixiangLi
 * @Date 2021/10/26
 */
@RestController
@RequestMapping("/discussPost")
@Slf4j
public class DiscussPostController {
    @Resource
    private DiscussPostService discussPostService;
    @Resource
    private UserService userService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private ObjectMapper mapper;
    @Resource
    private MessageProducer messageProducer;
    @Resource
    private CommonService commonService;

    @GetMapping("/{postId}")
    public ResultDTO getDiscussPost(@PathVariable Integer postId) throws JsonProcessingException {
        // 查缓存
        String value = redisUtil.getValueFromString(PREFIX_DISCUSS_POST, String.valueOf(postId));
        DiscussPost discussPost = null;
        if (value == null) {
            discussPost = discussPostService.findOne(postId);
            if (discussPost == null) {
                return ResultDTO.builder()
                        .code(ResponseCodeEnum.CLIENT_ERROR.getCode())
                        .message("帖子查询失败,可能被删除或不存在!")
                        .build();
            }
            redisUtil.saveIntoString(PREFIX_DISCUSS_POST, postId, mapper.writeValueAsString(discussPost));
        } else {
            discussPost = mapper.readValue(value, DiscussPost.class);
        }
        Map<String, Object> map = new HashMap<>(1);
        map.put("discussPost", discussPost);
        User user = userService.findUserById(discussPost.getUserId());
        map.put("user", user);
        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).data(map).build();
    }

    @PutMapping("/good/{postId}")
    public ResultDTO goodPost(@PathVariable Integer postId, HttpServletRequest request) throws JsonProcessingException {
        String value = redisUtil.getValueFromString(PREFIX_DISCUSS_POST, String.valueOf(postId));
        if (value == null) {
            // 认为帖子不存在
            return ResultDTO.builder()
                    .code(ResponseCodeEnum.CLIENT_ERROR.getCode())
                    .message("帖子查询失败,可能被删除或不存在!")
                    .build();
        }

        DiscussPost discussPost = mapper.readValue(value, DiscussPost.class);
        discussPost.setGood(discussPost.getGood() + 1);
        redisUtil.saveIntoString(PREFIX_DISCUSS_POST, postId, mapper.writeValueAsString(discussPost));

        // 发送点赞消息
        String token = CookieUtil.getValue(request, MAP_KEY_TOKEN);
        String currentUserId = redisUtil.getValueFromString(PREFIX_USER_ID, token);
        User user = commonService.getUserByUserId(currentUserId);
        Map<String, Object> map = new HashMap<>(1);
        map.put("discussPostTitle", discussPost.getTitle());
        map.put("discussPostId", discussPost.getId());
        MessageBO messageBO = MessageBO.builder()
                .fromUserName(user == null ? "路人甲" : user.getUsername())
                .toUserId(discussPost.getUserId())
                .data(map).build();
        messageProducer.sendMessage(TOPIC_GOOD, mapper.writeValueAsString(messageBO));

        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).build();
    }

    @PutMapping("/{postId}/{field}/{value}")
    @LoginRequired(roleType = 1)
    public ResultDTO updateValue(@PathVariable Integer postId, @PathVariable String field, @PathVariable Integer value) {
        discussPostService.updateValue(postId, field, value);
        return ResultDTO.builder().code(ResponseCodeEnum.SUCCESS.getCode()).build();
    }

}
